package com.ziyucoding.springboot.labs.lab10.seatdemo.athttpclient.orderservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ziyucoding.springboot.labs.lab10.seatdemo.athttpclient.orderservice.dao.OrderDao;
import com.ziyucoding.springboot.labs.lab10.seatdemo.athttpclient.orderservice.dataobject.OrderDO;
import com.ziyucoding.springboot.labs.lab10.seatdemo.athttpclient.orderservice.service.OrderService;
import io.seata.core.context.RootContext;
import io.seata.integration.http.DefaultHttpExecutor;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * 订单 service实现类
 *
 * @author ziyucoding
 * @date 2022-11-03
 **/
@Service
public class OrderServiceImpl implements OrderService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OrderDao orderDao;

    @Override
    @GlobalTransactional // 声明全局事务
    public Integer createOrder(Long userId, Long productId, Integer price) throws Exception {
        // 购买数量，暂时设置为 1。
        Integer amount = 1;

        logger.info("[createOrder] 当前 XID: {}", RootContext.getXID());

        // 扣减库存
        this.reduceStock(productId, amount);

        // 扣减余额
        this.reduceBalance(userId, price);

        // 保存订单
        OrderDO order = new OrderDO();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setPayAmount(amount * price);
        orderDao.saveOrder(order);
        logger.info("[createOrder] 保存订单: {}", order.getId());

        // 返回订单编号
        return order.getId();
    }

    /**
     * 扣除库存
     *
     * @param productId
     * @param amount
     * @return void
     **/
    private void reduceStock(Long productId, Integer amount) throws IOException {
        // 参数拼接
        JSONObject params = new JSONObject().fluentPut("productId", String.valueOf(productId))
                .fluentPut("amount", String.valueOf(amount));
        // 执行调用
        HttpResponse response = DefaultHttpExecutor.getInstance().executePost("http://127.0.0.1:9082", "/product/reduce-stock",
                params, HttpResponse.class);
        // 解析结果
        JSONObject result = JSON.parseObject(EntityUtils.toString(response.getEntity()));
        Boolean isSuccess = result.getBoolean("data");
        if (!isSuccess) {
            throw new RuntimeException("扣除库存失败");
        }
    }

    /**
     * 扣除余额
     *
     * @param userId
     * @param price
     * @return void
     **/
    private void reduceBalance(Long userId, Integer price) throws IOException {
        // 参数拼接
        JSONObject params = new JSONObject().fluentPut("userId", String.valueOf(userId))
                .fluentPut("price", String.valueOf(price));
        // 执行调用
        HttpResponse response = DefaultHttpExecutor.getInstance().executePost("http://127.0.0.1:9083", "/account/reduce-balance",
                params, HttpResponse.class);
        // 解析结果
        JSONObject result = JSON.parseObject(EntityUtils.toString(response.getEntity()));
        Boolean isSuccess = result.getBoolean("data");
        if (!isSuccess) {
            throw new RuntimeException("扣除余额失败");
        }
    }

}
